package org.starapp.generator;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.starapp.plugins.freemarker.Freemarker;
import org.starapp.utils.FileUtils;
import org.starapp.utils.ListUtils;
import org.starapp.utils.StringUtils;

public class GenerateMain {

	private String tableName;
	private String className;
	private String classAttrName;
	private String subPackageName;
	private String suffixName;
	private String functionName;
	private boolean isWebPage;
	private String firstPrimaryKey;

	private String firstPrimaryKeyFuncationName;
	
	private String firstPrimaryKeyType;
	
	private Table table;

	public String getFunctionName() {
		return functionName == null ? "" : functionName;
	}

	public boolean getIsWebPage() {
		return isWebPage;
	}

	public void setIsWebPage(boolean isWebPage) {
		this.isWebPage = isWebPage;
	}

	public String getFirstPrimaryKey() {
		return firstPrimaryKey;
	}

	public void setFirstPrimaryKey(String firstPrimaryKey) {
		this.firstPrimaryKey = firstPrimaryKey;
	}

	public void setFunctionName(String functionName) {
		this.functionName = functionName;
	}

	public void setSuffixName(String suffixName) {
		this.suffixName = suffixName;
	}

	public void setSubPackageName(String subPackageName) {
		this.subPackageName = subPackageName;
	}

	public String getSubPackageName() {
		return StringUtils.isEmpty(subPackageName) ? "" : subPackageName;
	}
	
	public String getFirstPrimaryKeyFuncationName() {
		firstPrimaryKeyFuncationName = getFirstPrimaryKey();
		if (!StringUtils.isEmpty(firstPrimaryKeyFuncationName)
				&& firstPrimaryKeyFuncationName.length() > 0) {
			firstPrimaryKeyFuncationName = firstPrimaryKeyFuncationName
					.substring(0, 1).toUpperCase()
					+ firstPrimaryKeyFuncationName.substring(1);
		}
		return firstPrimaryKeyFuncationName;
	}
	
	

	public void setTable(Table table) {
		this.table = table;
		this.tableName = table.getTableName();
		this.className = StringUtils.convent2javaFormat(ResourceUtils
				.getTablePrefix(), tableName);
		this.classAttrName = StringUtils.convent2javaLowerFormat(ResourceUtils
				.getTablePrefix(), tableName);
		this.firstPrimaryKey=table.getFirstPrimaryKey();
		this.firstPrimaryKeyFuncationName=this.getFirstPrimaryKeyFuncationName();
		
		if(!ListUtils.isEmpty(table.getFields())){
			for(TableField f:table.getFields()){
				if(f.getJavaColumnAttrName().equals(this.firstPrimaryKey)){
					this.firstPrimaryKeyType=f.getJavaColumnTypeName();
				}
			}
		}
	}

	public String getClassName() {
		return className;
	}

	public void setClassName(String className) {
		this.className = className;
	}

	public String getTemplateFileName() {
		return (isWebPage ? getFunctionName() : getSubPackageName()) + ".ftl";
	}

	private String getOutputFile() {
		return isWebPage ? ResourceUtils.getPageOutputFolder() : ResourceUtils
				.getSrcOutputFolder();
	}
	

	private String getFolderPath() {
		String path=
		FileUtils.getProjectPath()
				+ File.separator
				+ getOutputFile()
				+ (isWebPage ? ((StringUtils.isEmpty(ResourceUtils
						.getWebModule()) ? "" : File.separator
						+ ResourceUtils.getWebModule())+File.separator+classAttrName) : File.separator
						+ getSubPackageName());
		return path;
	}

	public String getFilePath() {
		return getFolderPath() + File.separator
				+ (isWebPage ? classAttrName : className) + getFunctionName()
				+ suffixName;
	}

	@SuppressWarnings("unchecked")
	public Map getDataMap() {
		Map data = new HashMap();
		data.put("author", ResourceUtils.getAuthor());
		data.put("package", ResourceUtils.getPackageName());
		data.put("className", table.getClassName());
		data.put("classAttrName", table.getClassAttrName());
		data.put("tableName", table.getTableName());
		data.put("subPackageName", subPackageName);
		data.put("fieldList", table.getFields());
		data.put("fkList", table.getForeignKeys());
		data.put("pkList", table.getPrimaryKeys());
		data.put("refList", table.getRefs());
		data.put("$", "$");
		data.put("module", ResourceUtils.getWebModule());
		data.put("firstPrimaryKey", firstPrimaryKey);
		
		data.put("firstPrimaryKeyFuncationName", firstPrimaryKeyFuncationName);
		data.put("firstPrimaryKeyType", firstPrimaryKeyType);
		
		return data;
	}

	@SuppressWarnings( { "deprecation" })
	public String getTemplateFolder() {
		return java.net.URLDecoder.decode(this.getClass().getResource("/")
				.getPath())
				+ ResourceUtils.getTemplateFolder();
	}

	public Writer getOut() {
		Writer out = null;
		try {
			File file = new File(getFolderPath());
			if (!file.exists()) {
				file.mkdirs();
			}
			file = new File(getFilePath());
			if (!file.exists()) {
				file.createNewFile();
			}
			out = new OutputStreamWriter(new FileOutputStream(file));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			out = new OutputStreamWriter(System.out);
		} catch (IOException ex) {
			ex.printStackTrace();
			out = new OutputStreamWriter(System.out);
		}
		return out;
	}

	public static void generate(String subPackageName, String suffixName,
			String functionName, boolean isWebPage) {
		DBConnection db = DBFactory.getDBConnection();
		// open connection;
		db.open();
		List<Table> list = db.getTableDataWithPrefix(ResourceUtils
				.getTablePrefix());
		if (!ListUtils.isEmpty(list)) {
			GenerateMain t = null;
			for (Table table : list) {
				if (table != null && !table.isHidden()) {
					t = new GenerateMain();
					t.setTable(table);
					t.setSubPackageName(subPackageName);
					t.setSuffixName(suffixName);
					t.setFunctionName(functionName);
					t.setIsWebPage(isWebPage);
					Freemarker.out(t.getTemplateFolder(), t.getDataMap(), t
							.getTemplateFileName(), t.getOut());
				}
			}
		}
		// close db
		db.close();
	}

	public static void generateEntity() {
		generate("entity", ".java", "", false);
	}

	public static void generateDao() {
		generate("dao", ".java", "Dao", false);
	}

	public static void generateService() {
		generate("service", ".java", "Service", false);
	}

	public static void generateRest() {
		generate("rest", ".java", "RestController", false);
	}

	public static void generateAction() {
		generate("action", ".java", "Controller", false);
	}

	public static void generatePageForm() {
		generate("", ".jsp", "Form", true);
	}

	public static void generatePageList() {
		generate("", ".jsp", "List", true);
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		//generateAction();
		//generateRest();
		//generateService();
		generateEntity();
		
	}
}
